#include <stdio.h>
#include <mpi.h>
#include "hdfs.h" 
#include "/proj/DIHPC/hadoop-0.20.203.0/conf/testHDFS/ParallelRead-16/ParallelRead/maxFlow.cpp"
#include "/proj/DIHPC/hadoop-0.20.203.0/conf/testHDFS/ParallelRead-16/ParallelRead/dataDistribution.cpp"
#include "/proj/DIHPC/hadoop-0.20.203.0/conf/testHDFS/ParallelRead-16/ParallelRead/mapToFlow.cpp"
#include "/proj/DIHPC/hadoop-0.20.203.0/conf/testHDFS/ParallelRead-16/ParallelRead/Assignment.cpp"

int main(int argc, char **argv) {

    if (argc != 6) {
       // fprintf(stderr, "Usage: hdfs_read <filename> <filesize> <buffersize>\n");
		fprintf(stderr, "Usage: parallelReader <hostname> <filename> <nHosts> <nFiles> <nCopies>\n");
        exit(-1);
    }
    
    hdfsFS fs = hdfsConnect("default", 0);
    if (!fs) {
        fprintf(stderr, "Oops! Failed to connect to hdfs!\n");
        exit(-1);
    } 

	/*/*********************get dataDistribution**************************/
	printf("Hello World!\n");
/*	char* FileName = argv[1];
	int nFiles = strtoul(argv[2], NULL, 10);
	int nCopies = strtoul(argv[3], NULL, 10);
*/

	char* HostName = argv[1];
	char* FileName = argv[2];
	int nHosts = strtoul(argv[3], NULL, 10);
	int nFiles = strtoul(argv[4], NULL, 10);
	int nCopies = strtoul(argv[5], NULL, 10);

	struct DCmonitor *monitor = DCmonitor_create(HOSTS, HostName, FileName, nHosts, nFiles, nCopies);

	//struct DCmonitor *monitor = DCmonitor_create(HOSTS, FileName, nFiles, nCopies);
//	DCscheduler_showmap(monitor);

	/*********************************run maxflow**************************/
	int nfiles = monitor->nr_files, mhosts = monitor->nr_hosts;
	int V = nfiles + mhosts + 2;
	int **graph = map_flow(monitor);
//	flow_showgraph(graph, V);
	cout << "The maximum possible flow is " << fordFulkerson(graph, 0, nfiles + mhosts + 1, V) << "\n";
//	flow_showgraph(graph, V);

	/*****************************assignment***********************************/
	int** exmap;
	exmap = (int **)malloc(sizeof(int *)* (mhosts+1));
	for (int i = 0; i< mhosts+1; i++)
		exmap[i] = (int *)malloc((nfiles/mhosts) * sizeof(int));

	extractMap(graph, nfiles, mhosts, exmap);
//	showgAssignment(exmap, mhosts + 1, nfiles / mhosts);

	/***************************************************************************/
	clock_t t_start, t_end;
	int rank, size;
    MPI_Init (&argc, &argv);	
    MPI_Comm_rank (MPI_COMM_WORLD, &rank);	
    MPI_Comm_size (MPI_COMM_WORLD, &size);	

	/**************************obtain assignment************************************/
/*	int* assignedFiles;
	assignedFiles = (int *)malloc((n/m) * sizeof(int));
	for (int i = 0; i < n / m; i++)
		assignedFiles[i] = -1;
*/		
	/**/
	tSize fileTotalSize = 60000000;
	tSize bufferSize = 1024;

	char* buffer = (char*)malloc(sizeof(char)* bufferSize);
	if (buffer == NULL) {
		return -2;
	}

	for (int i = 0; i < nfiles / mhosts; i++)
	{
		t_start = clock();
		double profile_time = MPI_Wtime();

		char* FileName = argv[1];
		char rfile[80];
	
	//	int findex = i + rank * nfiles / mhosts;

		int findex = exmap[rank+1][i]; //i + rank * nfiles / mhosts;
		strcpy(rfile, monitor->file[findex-1]); 

		hdfsFile readFile = hdfsOpenFile(fs, rfile, O_RDONLY, bufferSize, 0, 0);
		if (!readFile) {
			fprintf(stderr, "Failed to open %s for reading!\n", rfile);
			exit(-2);
		}

		tSize curSize = bufferSize;
		for (; curSize == bufferSize;) {
			curSize = hdfsRead(fs, readFile, (void*)buffer, curSize);
		}
		
		hdfsCloseFile(fs, readFile);	

		profile_time = MPI_Wtime() - profile_time;
		t_end = clock();
		
		//printf("%d %fs %fs\n", rank, profile_time, (double)(t_end - t_start) / (double)CLOCKS_PER_SEC);
		printf("%d \t %f \n", findex-1, profile_time);
	}	

	free(buffer);
    hdfsDisconnect(fs);

	MPI_Finalize();
    
	return 0;
}
/*
#include <stdio.h>
#include <mpi.h>


int main (argc, argv)
     int argc;
     char *argv[];
{
  int rank, size;
  char hostname[1024];
  hostname[1023] = '\0';
  gethostname(hostname, 1023);

  MPI_Init (&argc, &argv);	
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);	
  MPI_Comm_size (MPI_COMM_WORLD, &size);	
  printf( "Hello world from process %d of %d on %s\n ", rank, size, hostname );
  MPI_Finalize();
  return 0;
}

*/